package engine.scene;

import math.Maths;
import math.vector.Vecmath;
import math.vector.vec2f;
import math.vector.vec3f;

public class Tri 
{
    
    public static final int NUM_VERTICES = 3;
    
    
    public vec3f[] verts;
    //<editor-fold defaultstate="collapsed" desc="setVertexAt">
    public void setVertexAt(int index, vec3f vert)
    {
        this.verts[index] = vert;
    }
    
    public void setVertexAt(int index, float vx, float vy, float vz)
    {
        this.setVertexAt(index, new vec3f(vx, vy, vz));
    }
    //</editor-fold>
    
    public vec3f[] norms;
    //<editor-fold defaultstate="collapsed" desc="setNormalAt">
    public void setNormalAt(int index, vec3f normal)
    {
        this.norms[index] = normal;
    }
    
    public void setNormalAt(int index, float nx, float ny, float nz)
    {
        this.setNormalAt(index, new vec3f(nx, ny, nz));
    }
    //</editor-fold>
    
    public vec2f[] texCoords;
    //<editor-fold defaultstate="collapsed" desc="setTexCoordAt">
    public void setTexCoordAt(int index, vec2f texCoord)
    {
        this.texCoords[index] = texCoord;
    }
    
    public void setTexCoordAt(int index, float s, float t)
    {
        this.setTexCoordAt(index, new vec2f(s, t));
    }
    //</editor-fold>
    
    
    public Tri() 
    {
        this.verts = new vec3f[Tri.NUM_VERTICES];
        this.norms = new vec3f[Tri.NUM_VERTICES];
        this.texCoords = new vec2f[Tri.NUM_VERTICES];
        for (int i = 0; i < Tri.NUM_VERTICES; i++) 
        {
            this.verts[i] = new vec3f();
            this.norms[i] = new vec3f();
            this.texCoords[i] = new vec2f();
        }
    }
    
    public Tri(
            float x0, float y0, float z0, float nx0, float ny0, float nz0, float s0, float t0, 
            float x1, float y1, float z1, float nx1, float ny1, float nz1, float s1, float t1, 
            float x2, float y2, float z2, float nx2, float ny2, float nz2, float s2, float t2)
    {
        this();
        this.verts[0] = new vec3f(x0, y0, z0);
        this.verts[1] = new vec3f(x1, y1, z1);
        this.verts[2] = new vec3f(x2, y2, z2);
        this.norms[0] = new vec3f(nx0, ny0, nz0);
        this.norms[1] = new vec3f(nx1, ny1, nz1);
        this.norms[2] = new vec3f(nx2, ny2, nz2);
        this.texCoords[0] = new vec2f(s0, t0);
        this.texCoords[1] = new vec2f(s1, t1);
        this.texCoords[2] = new vec2f(s2, t2);
    }
    
    public Tri(
            vec3f v0, vec3f n0, float s0, float t0, 
            vec3f v1, vec3f n1, float s1, float t1, 
            vec3f v2, vec3f n2, float s2, float t2)
    {
        this(
            v0.x, v0.y, v0.z, n0.x, n0.y, n0.z, s0, t0, 
            v1.x, v1.y, v1.z, n1.x, n1.y, n1.z, s1, t1, 
            v2.x, v2.y, v2.z, n2.x, n2.y, n2.z, s2, t2
        );
    }
    
    public Tri(
            vec3f v0, vec3f n0, vec2f tc0, 
            vec3f v1, vec3f n1, vec2f tc1, 
            vec3f v2, vec3f n2, vec2f tc2)
    {
        this(
            v0.x, v0.y, v0.z, n0.x, n0.y, n0.z, tc0.x, tc0.y, 
            v1.x, v1.y, v1.z, n1.x, n1.y, n1.z, tc1.x, tc1.y, 
            v2.x, v2.y, v2.z, n2.x, n2.y, n2.z, tc2.x, tc2.y
        );
    }
    
    public Tri(vec3f[] vertices, vec3f[] normals, vec2f[] texCoords) 
    {
        this(
            vertices[0], normals[0], texCoords[0], 
            vertices[1], normals[1], texCoords[1], 
            vertices[2], normals[2], texCoords[2]
        );
    }
    
    public Tri(Tri tri) 
    {
        this(tri.verts, tri.norms, tri.texCoords);
    }
    
    
    public boolean onNormalSide(vec3f v) 
    {
        float dotProd0 = Vecmath.getDotProductOf(this.norms[0], v);
        float dotProd1 = Vecmath.getDotProductOf(this.norms[1], v);
        float dotProd2 = Vecmath.getDotProductOf(this.norms[2], v);
        float average = (dotProd0 + dotProd1 + dotProd2) * Maths.ONE_OVER_3;
        return (average >= 0);
    }
    
    public void calcSurfaceNormal() 
    {
        vec3f normal = Vecmath.getSurfaceNormalOf(
            this.verts[0], this.verts[1], this.verts[2]
        );
        this.norms[0] = normal;
        this.norms[1] = normal;
        this.norms[2] = normal;
    }
    
    public String toString() 
    {
        String s = "";
        for (int i = 0; i < Tri.NUM_VERTICES; i++) 
        {
            s += "TRIANGLE" + "\n";
            s += "   xyz: " + this.verts[i].toString() + "\n";
            s += "   st: " + this.texCoords[i].toString() + "\n";
            s += "   norm: " + this.norms[i].toString() + "\n";
        }
        return s;
    }

}
